package controller;

import com.alibaba.fastjson.JSONArray;
import org.junit.jupiter.api.Test;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ConcurrentModel;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import pojo.FileInformation;
import pojo.User;
import pojo.UserInformation;
import service.File.FileService;
import service.User.UserService;

import javax.annotation.Resource;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author HZY
 */
@Controller
@RequestMapping("/userService")
public class userServiceController {
    public User myUser;
    @Resource
    private UserService userService;
    @Resource
    private FileService fileService;

    /**
     * 获取用户信息视图
     *
     * @param userId 需要查询的用户id
     * @param model  包含("User", user.getMap())
     * @return 跳转到用户信息视图"/UserView/UserInformationView"
     */
    @RequestMapping("/viewUser")
    @ResponseBody
    public Object viewUserInformation(
            @RequestParam(value = "UserId") int userId,
            Model model) throws IOException {
        if (myUser==null){
            myUser=userService.getUser(userId);
        }
        if (myUser.getId()==userId) {
            loadPersonalInformation(myUser, model);
            loadTheNewsOfInterest(myUser,model);
        }else {
            loadPersonalInformation(userService.getUser(userId), model);
        }
        System.out.println();
        return JSONArray.toJSONString(model.asMap());
    }

    /**
     * 修改用户登入信息
     * （修改密码，换绑手机|邮箱）
     *
     * @param userId 目标id
     * @param type   操作类型
     * @param value  修改值
     */
    @RequestMapping("/reviseUserLoginInformation")
    public void reviseUserLoginInformation(
            @RequestParam(value = "UserId") int userId,
            @RequestParam(value = "type") int type,
            @RequestParam(value = "value") String value) {
        //缺少验证过程
        userService.reviseUser(userId, type, value);
    }


    /**
     * 创建新用户的设置信息文件，日志文件
     *
     * @param userId 新用户Id
     * @throws IOException 异常
     */
    public static void createUserInformation(int userId) throws IOException {
        Path directorie = Path.of("E:\\java\\Spring\\lightblog\\file/" + userId + "/UserInformation");
        Files.createDirectories(directorie);
        Path setFile = Path.of(String.valueOf(directorie), "UserSetInformation.usi");
        Files.copy(Path.of("E:\\java\\Spring\\lightblog\\file/UserSetInformation_templet.usi"), setFile);
        Path logFile = Path.of(String.valueOf(directorie), "UserLogInformation.usi");
        Files.copy(Path.of("E:\\java\\Spring\\lightblog\\file/UserLogInformation_templet.usi"), logFile);

    }

    /**
     * 加载基本用户信息
     * @param user 需求的用户
     * @param model 空
     * @throws IOException io
     */
    public void loadPersonalInformation(User user, Model model) throws IOException {
        Map<String, Set<String>> map = readUserSetInformation(Path.of("E:\\java\\Spring\\lightblog\\file/" + user.getId() + "/UserInformation/UserSetInformation.usi"));

        Map<Integer,User> userMap = new HashMap<>();
        userMap.put(user.getId(),user);
        Set<String> t = map.get("Following");
        Set<Integer> my=new HashSet<>();
        for (String s:t){
            User ruser = userService.getUser(Integer.parseInt(s));
            userMap.put(ruser.getId(),ruser);
            my.add(Integer.parseInt(s));
        }
        model.addAttribute("Following",my);
        model.addAttribute("userMap",userMap);

        Map<Integer,FileInformation> fileMap = new HashMap<>();
        t = map.get("Stars");
        my=new HashSet<>();
        for (String s:t){
            if (s.isEmpty()){
                break;
            }
            FileInformation rFile = fileService.getFile(Integer.parseInt(s));
            if (rFile==null){
                continue;
            }
            fileMap.put(rFile.getFileId(),rFile);
            my.add(Integer.parseInt(s));
        }
        model.addAttribute("Stars",my);

        t = map.get("Depot");
        my=new HashSet<>();
        for (String s:t){
            FileInformation rFile = fileService.getFile(Integer.parseInt(s));
            fileMap.put(rFile.getFileId(),rFile);
            my.add(Integer.parseInt(s));
        }
        model.addAttribute("Depot",my);
        model.addAttribute("fileMap",fileMap);

        Map<String, List<String[]>> logmap = getdynamic(user.getId());
        model.addAttribute("log",logmap);
//        System.out.println(model.asMap().toString());
    }
    /**
     * 加载关注的动态
     * @param user 登入后的用户
     * @param model 已载入登入后的用户的信息
     * @throws IOException
     */
    public void loadTheNewsOfInterest(User user, Model model) throws IOException {
        Map<String, Set<String>> map = readUserSetInformation(Path.of("E:\\java\\Spring\\lightblog\\file/" + user.getId() + "/UserInformation/UserSetInformation.usi"));
        Map<Integer,User> userMap = new HashMap<>();
        Map<Integer,FileInformation> fileMap = new HashMap<>();
        Set<String> following = map.get("Following");
        Map<String, List<String[]>> logmap = (Map<String, List<String[]>>) model.getAttribute("log");
        userMap.put(user.getId(),user);
        for (String s : following) {
            User ruser = userService.getUser(Integer.parseInt(s));
            userMap.put(ruser.getId(),ruser);
            Map<String, List<String[]>> rmap = getdynamic(ruser.getId());
            for (String date : rmap.keySet()) {
                if (logmap.containsKey(date)) {
                    logmap.put(date,mergeLog(logmap.get(date),rmap.get(date)));
                }else {
                    logmap.put(date,rmap.get(date));
                }
            }
        }
        model.addAttribute("log",logmap);
        model.addAttribute("userMap",userMap);
//        System.out.println("响应数据：\n"+model.asMap().toString());
    }
    /**
     * 合并链表
     */
    public List<String[]> mergeLog(List<String[]> list1,List<String[]> list2){
        if (list1==null) {
            return list2;
        }
        if (list2==null) {
            return list1;
        }
        list1.addAll(list2);
        list1.sort(Comparator.comparing(this::extractionTime));
        return list1;
    }
    /**
     * 提取时间
     */
    public LocalTime extractionTime(String[] s){
        String substring = s[0];
        return LocalTime.parse(substring);
    }

    /**
     * 获取用户设置信息（读取用户设置文件）
     *
     * @param accountFile 用户设置文件路径
     */
    public Map<String, Set<String>> readUserSetInformation(Path accountFile) {
        UserInformation userInformation = new UserInformation(accountFile);
        return userInformation.getMap();
    }

    /**
     * 修改用户设置信息
     * （变更关注列表、收藏列表、自身创作列表）
     *
     * @param user  自身用户
     * @param type  修改类型（关注，收藏，自身创作）
     * @param value 变更后的id
     * @param flag  操作类型（true->添加，false->删除）
     * @throws IOException 读取文件时出现的异常
     */
    public void reviseUserSetInformation(User user, int type, int value, boolean flag) throws IOException {
        File file = new File("E:\\java\\Spring\\lightblog\\file/" + user.getId() + "/UserInformation/UserSetInformation.usi");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < 3; i++) {
            String s = randomAccessFile.readLine() + '\n';
            if (i == type) {
                String[] split = s.split("=");
                if (flag) {
                    s = split[0] + "=" + value + "," + split[1];
                } else {
                    String[] split1 = split[1].split(value + ",");
                    s = split[0] + "=" + split1[0] + split1[1];
                }
            }
            stringBuffer.append(s);
        }
        Path path = Path.of("E:\\java\\Spring\\lightblog\\file/" + user.getId() + "/UserInformation");
        Path t_userInformation = Files.createTempFile(path, "t_UserSetInformation", ".usi");
        Files.writeString(t_userInformation, stringBuffer);
        randomAccessFile.close();
        Files.delete(file.toPath());
        Files.copy(t_userInformation, file.toPath());
        Files.delete(t_userInformation);
    }

    /**
     * 追加日志
     * @param userId
     * @param type
     * @param fileId
     * @throws IOException
     */
    static public void addEndLog(int userId, int type, int fileId) throws IOException {
        File path = new File("E:\\java\\Spring\\lightblog\\file/" + userId + "/UserInformation/UserLogInformation.usi");
        LocalDate oldLocalDate = LocalDate.ofInstant(new Date(path.lastModified()).toInstant(), ZoneOffset.ofHours(8));
        LocalDate newLocalDate = LocalDate.now();
        String oneLog = "";
        if (newLocalDate.equals(oldLocalDate)) {
            oneLog = "#" + newLocalDate.toString() + "\n";
        }
        String s = "";
        switch (type) {
            case 0:
                s = " Create ";
                break;
            case 1:
                s = " Renew ";
                break;
            case 2:
                s = " Delete ";
                break;
            default:
                s = "异常操作";
                break;
        }
        oneLog +=
                LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) +
                        s + fileId + "\n";
        FileOutputStream fileOutputStream = new FileOutputStream(path, true);
        fileOutputStream.write(oneLog.getBytes());
        fileOutputStream.flush();
        fileOutputStream.close();
    }

    /**
     * 获取最新动态（三天）
     * @param userId
     * @return
     * @throws IOException
     */
    public Map<String, List<String[]>> getdynamic(
            int userId
    ) throws IOException {
        Map<String, List<String[]>> map = new HashMap<>();
        Path path = Path.of("E:\\java\\Spring\\lightblog\\file/" + userId + "/UserInformation/UserLogInformation.usi");
        String string;
        BufferedReader reader = Files.newBufferedReader(path);
        List<String[]> list = new ArrayList<>();
        while ((string = reader.readLine()) != null) {
            if (string.charAt(0) == '#') {
                //读取日期
                LocalDate localDate = LocalDate.parse(string.substring(1));
                list = new ArrayList<>();
                map.put(localDate.toString(), list);
            } else {
                //读取日志
                String s=string+" "+userId;
                list.add(s.split(" "));
            }
        }
        reader.close();
        return map;
    }
}
